/*

 * Copyright (C) 2021 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package me.panpf.sketch.sample.vt.ui.listcontainer.progressindicator;

import me.panpf.sketch.sample.vt.utils.AttrUtils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.app.Context;

/**
 * AVLoadingIndicatorView
 *
 * @author hw
 * @since 2021/6/23
 */
public class AVLoadingIndicatorView extends Component implements Component.DrawTask,
        Component.BindStateChangedListener {

    // Sizes (with defaults in DP)
    public static final int DEFAULT_SIZE = 30;

    // attrs
    private int mIndicatorId;
    private int mIndicatorColor;
    private boolean mHasAnimation = false;
    private Paint mPaint;

    public AVLoadingIndicatorView(Context context) {
        super(context);
        init(context, null, null);
    }

    public AVLoadingIndicatorView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init(context, attrSet, null);
    }

    public AVLoadingIndicatorView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(context, attrSet, styleName);
    }

    private void init(Context context, AttrSet attrSet, String styleName) {
        mIndicatorColor = AttrUtils.getColorFromAttr(attrSet, "avl_indicator_color", Color.WHITE.getValue());
        mPaint = new Paint();
        mPaint.setColor(new Color(mIndicatorColor));
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mPaint.setAntiAlias(true);
        if (!mHasAnimation) {
            mHasAnimation = true;
            applyAnimation();
        }
        setEstimateSizeListener((widthEstimateConfig, heightEstimateConfig) -> {
            int width = measureDimension(dp2px(DEFAULT_SIZE, getContext()), widthEstimateConfig);
            int height = measureDimension(dp2px(DEFAULT_SIZE, getContext()), heightEstimateConfig);
            setEstimatedSize(width, height);
            return true;
        });
        addDrawTask(this);
    }

    /**
     * setIndicatorId
     *
     * @param indicatorId indicatorId
     */
    public void setIndicatorId(int indicatorId) {
        mIndicatorId = indicatorId;
    }

    /**
     * setIndicatorColor
     *
     * @param color color
     */
    public void setIndicatorColor(int color) {
        mIndicatorColor = color;
        mPaint.setColor(new Color(mIndicatorColor));
        this.invalidate();
    }

    private int measureDimension(int defaultSize, int measureSpec) {
        int result = defaultSize;
        int specMode = EstimateSpec.getMode(measureSpec);
        int specSize = EstimateSpec.getSize(measureSpec);
        if (specMode == EstimateSpec.PRECISE) {
            result = specSize;
        } else if (specMode == EstimateSpec.NOT_EXCEED) {
            result = Math.min(defaultSize, specSize);
        } else {
            result = defaultSize;
        }
        return result;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        drawIndicator(canvas);
    }

    @Override
    public void arrange(int left, int top, int width, int height) {
        super.arrange(left, top, width, height);
        if (!mHasAnimation) {
            mHasAnimation = true;
            applyAnimation();
        }
    }

    @Override
    public void setVisibility(int visibility) {
        if (getVisibility() != visibility) {
            super.setVisibility(visibility);
        }
    }

    @Override
    public void onComponentBoundToWindow(Component component) {
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {
    }

    void drawIndicator(Canvas canvas) {
    }

    /**
     * applyAnimation
     */
    public void applyAnimation() {
    }

    /**
     * destroy
     */
    public void destroy() {
        mHasAnimation = true;
        mPaint = null;
    }

    private final static double NORMAL_PIXEL_DENSITY = 160d;

    private static int dp2px(float dp, Context context) {
        float scale = context.getResourceManager().getDeviceCapability().screenDensity;
        return (int) (dp * scale / NORMAL_PIXEL_DENSITY + 0.5f);
    }
}